#include <aknnotewrappers.h>
#include <aknviewappui.h>
#include <eikmenub.h>
#include <avkon.hrh>
#include <stringloader.h>
#include <s32file.h>

#include <StopWatch_2005B914.rsg>
#include "StopWatch.hrh"

#include "StopwatchModel.h"
#include "StopWatchContainer.h"

#include "StopWatchView.h"

namespace
{

_LIT(KStopWatchFile, "StopWatch.dat");

}

CStopWatchView::CStopWatchView()
{}

CStopWatchView::~CStopWatchView()
{
  delete iModel;
  iModel = NULL;

  delete iStopWatchContainer;
  iStopWatchContainer = NULL;

  delete iPeriodicTimeUpdate;
  iPeriodicTimeUpdate = NULL;
}

CStopWatchView* CStopWatchView::NewL()
{
  CStopWatchView* self = CStopWatchView::NewLC();
  CleanupStack::Pop(self);
  return self;
}

CStopWatchView* CStopWatchView::NewLC()
{
  CStopWatchView* self = new (ELeave) CStopWatchView();
  CleanupStack::PushL(self);
  self->ConstructL();
  return self;
}

void CStopWatchView::ConstructL()
{
  BaseConstructL(R_STOPWATCH_VIEW);
  iPeriodicTimeUpdate = CPeriodic::NewL(CActive::EPriorityHigh);
  iModel = CStopwatchModel::NewL(*this);
}

TUid CStopWatchView::Id() const
{
  return TUid::Uid(EStopWatchViewId);
}

void CStopWatchView::HandleCommandL(TInt aCommand)
{
  TBool commandHandled = EFalse;
  switch (aCommand)
  {
    case ECmdStopWatchRestart:
      iModel->Reset();
    case ECmdStopWatchStart:
      iModel->Start();
//      UpdateUiL();
      break;
    case ECmdStopWatchStop:
      iModel->Stop();
//      UpdateUiL();
      break;
    case ECmdStopWatchSnapshot:
      TRAP_IGNORE(iModel->MakeSnapshotL());
      break;
    case ECmdStopWatchClear:
      iModel->Stop();
      iModel->Reset();
      break;
    default:
      AppUi()->HandleCommandL(aCommand);
      break;
  }
}

void CStopWatchView::DoActivateL(const TVwsViewId& /*aPrevViewId*/, TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/)
{
//  SetupStatusPaneL();

  if (iStopWatchContainer == NULL)
  {
    iStopWatchContainer = CStopWatchContainer::NewL(ClientRect(), NULL, this);
    iStopWatchContainer->SetMopParent(this);
    AppUi()->AddToStackL(*this, iStopWatchContainer);
  }

  TRAP_IGNORE(RestoreStateL());
}

void CStopWatchView::DoDeactivate()
{
//  CleanupStatusPane();

  if (iStopWatchContainer != NULL)
  {
    AppUi()->RemoveFromViewStack(*this, iStopWatchContainer);
    delete iStopWatchContainer;
    iStopWatchContainer = NULL;
  }
  TRAP_IGNORE(StoreStateL());
}

void CStopWatchView::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
{
  if ( aResourceId == R_STOPWATCH_OPTIONS_MENU_PANE )
  {
    if ( iPeriodicTimeUpdate->IsActive() )
    {
      aMenuPane->DeleteMenuItem(ECmdStopWatchStart);
      aMenuPane->DeleteMenuItem(ECmdStopWatchClear);
//      aMenuPane->DeleteMenuItem(ECmdExportStopWatchData);
    }
    else
    {
      if ( iModel->Value() == 0 )
      {
        aMenuPane->DeleteMenuItem(ECmdStopWatchSnapshot);
        aMenuPane->DeleteMenuItem(ECmdStopWatchClear);
//        aMenuPane->DeleteMenuItem(ECmdStopWatchRestart);
      }
      aMenuPane->DeleteMenuItem(ECmdStopWatchStop);
    }
  }
}

TTimeIntervalMicroSeconds32 CStopWatchView::StopWatchUpdateInterval() const
{
  const TTimeIntervalMicroSeconds32 interval(100*1000);
  return interval;
}

TInt CStopWatchView::TimeUpdateCB(TAny* aThis)
{
  TRAP_IGNORE(reinterpret_cast<CStopWatchView*>(aThis)->TimeUpdateCallbackL());
  return ETrue;
}

void CStopWatchView::TimeUpdateCallbackL()
{
  iStopWatchContainer->SetDisplayValueL(iModel->Value());
}

void CStopWatchView::HandleForegroundEventL(TBool aForeground)
{
  CAknView::HandleForegroundEventL(aForeground);
  if ( !aForeground && iPeriodicTimeUpdate->IsActive() )
  {
//    iIsStarted = ETrue;
    StopUpdateStopWatch();
  }
  else if ( iModel->IsRunning() && aForeground )
  {
    StartUpdateStopWatch();
//    iIsStarted = EFalse;
  }
}

void CStopWatchView::StartUpdateStopWatch()
{
  if ( iPeriodicTimeUpdate->IsActive() )
    return;

  TTimeIntervalMicroSeconds32 interval = StopWatchUpdateInterval();
  iPeriodicTimeUpdate->Start(interval, interval, TCallBack(CStopWatchView::TimeUpdateCB, this));
}

void CStopWatchView::StopUpdateStopWatch()
{
  iPeriodicTimeUpdate->Cancel();
}

void CStopWatchView::RestoreStateL()
{
  iModel->LoadL(CCoeEnv::Static()->FsSession(), KStopWatchFile());
//  if ( iStopWatchContainer )
//    iStopWatchContainer->SetSnapshotsL(iModel->Snapshots());
}

void CStopWatchView::StoreStateL()
{
  iModel->SaveL(CCoeEnv::Static()->FsSession(), KStopWatchFile());
}

void CStopWatchView::UpdateUiL()
{
  iStopWatchContainer->SetDisplayValueL(iModel->Value());
  if ( iModel->IsRunning() )
  {
    StartUpdateStopWatch();
    Cba()->SetCommandSetL(R_STOPWATCH_OPTIONS_STOP_CBA);
  }
  else
  {
    StopUpdateStopWatch();
    Cba()->SetCommandSetL(R_STOPWATCH_OPTIONS_START_CBA);
  }
  Cba()->MakeVisible(ETrue);
  Cba()->DrawNow();
}

void CStopWatchView::StopwatchStarted()
{
  StartUpdateStopWatch();
  TRAP_IGNORE(CStopWatchView::UpdateUiL());
}

void CStopWatchView::StopwatchStopped()
{
  StopUpdateStopWatch();
  TRAP_IGNORE(CStopWatchView::UpdateUiL());
}

void CStopWatchView::StopwatchNewSnapshotValue(const TSnapshot& aSnapshot)
{
  TRAP_IGNORE(iStopWatchContainer->AddTimeSnapshotL(aSnapshot));
}

void CStopWatchView::StopwatchReset()
{
  TRAP_IGNORE(StopwatchResetL());
}

void CStopWatchView::StopwatchResetL()
{
  iStopWatchContainer->SetDisplayValueL(iModel->Value());
  iStopWatchContainer->SetSnapshotsL(iModel->Snapshots());
}

